home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / pctj8403.arc / EX4PRIM.ASM < prev    next >
Assembly Source File  |  1984-01-30  |  17KB  |  464 lines

  1. ; ROUTINES FOR CHAPTER 4 - GRAPHICS - ELEMENTARY FUNCTIONS
  2. ;
  3. ; For 320 x 200 color graphics mode
  4. ;
  5. ;**********************************************************
  6. datas   segment public
  7. ;
  8.         public  x0,y0,x1,y1,x2,y2
  9.         public  color
  10. ;
  11. ; public parameters
  12. x0      dw      ?
  13. y0      dw      ?
  14. x1      dw      ?
  15. y1      dw      ?
  16. x2      dw      ?
  17. y2      dw      ?
  18. color   dw      ?
  19. ;
  20. ; tables of color masks for filling boxes
  21. cbytes  db      000h, 055h, 0AAh, 0FFh
  22. ;
  23. xtable  dw      0FFC0h, 0FFF0h, 0FFFCh, 0FFFFh
  24.         dw      03FC0h, 03FF0h, 03FFCh, 03FFFh
  25.         dw      00FC0h, 00FF0h, 00FFCh, 00FFFh
  26.         dw      003C0h, 003F0h, 003FCh, 003FFh
  27. ;
  28. ; table of color masks for plotting points
  29. ctable  dw      0003Fh,0403Fh,0803Fh,0C03Fh
  30.         dw      000CFh,010CFh,020CFh,030CFh
  31.         dw      000F3h,004F3h,008F3h,00CF3h
  32.         dw      000FCh,001FCh,002FCh,003FCh
  33. ;
  34. datas   ends
  35. ;**********************************************************
  36. video   segment at 0B800h
  37. video   ends
  38. ;**********************************************************
  39. ex4prim segment
  40. ;
  41.         public  cls
  42.         public  setpt,xorpt,locate
  43.         public  setbox,xorbox
  44. ;
  45.         assume  cs:ex4prim,ds:datas,es:video
  46. ;
  47. ;----------------------- routine begins -------------------------------+
  48. ; ROUTINE TO CLEAR THE GRAPHICS SCREEN
  49. ;
  50. cls     proc    far;
  51.         push    cx              ; save registers
  52.         push    ax
  53. ;
  54. ; set up the registers
  55.         mov     cx,2000h        ; word count of whole screen
  56.         mov     ax,0            ; zero pattern for the screen
  57.         mov     di,ax           ; set starting address
  58.         cld                     ; go in forward direction
  59. ;
  60. ; clear the screen with a single string operation
  61.         rep     stosw           ; this clears the screen
  62. ;
  63.         pop     ax              ; restore registers
  64.         pop     cx
  65.         ret
  66. cls     endp
  67. ;----------------------- routine ends --------------------------------+
  68. ;----------------------- routine begins -------------------------------+
  69. ; ROUTINE TO PLOT A POINT ON MEDIUM RES COLOR SCREEN
  70. ;
  71. setpt   proc    far
  72. ;
  73.         push    bx              ; save registers
  74.         push    si
  75.         push    ax
  76. ;
  77. ; multiply y-coord by bytes per row and adjust for even/odd lines
  78.         mov     ax,di           ; get y-coord into low part
  79.         mov     ah,al           ;  and into high part
  80.         and     ax,01FEh        ; mask off unwanted parts
  81.         sal     ax,1            ; times 4
  82.         sal     ax,1            ; times 8
  83.         sal     ax,1            ; times 16
  84.         mov     bx,ax           ; goes into address
  85.         and     bh,7            ; without adjustment
  86.         sal     ax,1            ; times 32
  87.         sal     ax,1            ; times 64
  88.         add     bx,ax           ; address gets y-coord times 80
  89. ;
  90. ; add x-coord to address
  91.         mov     ax,si           ; get x-coordinate
  92.         sar     ax,1            ; divide
  93.         sar     ax,1            ; by 4
  94.         add     bx,ax           ; here is the address
  95. ;
  96. ; compute the rotated mask and color
  97.         and     si,3            ; just pixel position into the index
  98.         sal     si,1            ; index times 2
  99.         sal     si,1            ; index times 4
  100.         add     si,dx           ; 4*pixel position + color
  101.         sal     si,1            ; 8*pixel position + 2*color
  102.         mov     ax,ctable[si]   ; look up rotated color and mask
  103. ;
  104. ; insert the color into the video byte
  105.         and     al,es:[bx]      ; get old byte & remove old pixel
  106.         or      al,ah           ; insert new color
  107.         mov     es:[bx],al      ; put the byte back
  108. ;
  109.         pop     ax              ; restore registers
  110.         pop     si
  111.         pop     bx
  112.         ret
  113. ;
  114. setpt   endp
  115. ;----------------------- routine ends --------------------------------+
  116. ;----------------------- routine begins ------------------------------+
  117. ; ROUTINE TO XOR A POINT ONTO MEDIUM RES COLOR SCREEN
  118. ;
  119. xorpt   proc    far
  120. ;
  121.         push    bx              ; save registers
  122.         push    si
  123.         push    ax
  124. ;
  125. ; multiply y-coord by bytes per row and adjust for even/odd lines
  126.         mov     ax,di           ; get y-coord into low part
  127.         mov     ah,al           ;  and into high part
  128.         and     ax,01FEh        ; mask off unwanted parts
  129.         sal     ax,1            ; times 4
  130.         sal     ax,1            ; times 8
  131.         sal     ax,1            ; times 16
  132.         mov     bx,ax           ; goes into address
  133.         and     bh,7            ; without adjustment
  134.         sal     ax,1            ; times 32
  135.         sal     ax,1            ; times 64
  136.         add     bx,ax           ; address gets y-coord times 80
  137. ;
  138. ; add x-coord to address
  139.         mov     ax,si           ; get x-coordinate
  140.         sar     ax,1            ; divide
  141.         sar     ax,1            ; by 4
  142.         add     bx,ax           ; here is the address
  143. ;
  144. ; compute the mask for color and use it
  145.         and     si,3            ; just the bit count into the index
  146.         sal     si,1            ; index times 2
  147.         sal     si,1            ; index times 4
  148.         add     si,dx           ; 4*pixel position + color
  149.         sal     si,1            ; 8*pixel position + 2*color
  150.         mov     ax,ctable[si]   ; look up the masks
  151.         xor     es:[bx],ah      ; xor the byte with the color
  152. ;
  153.         pop     ax              ; restore registers
  154.         pop     si
  155.         pop     bx
  156.         ret
  157. ;
  158. xorpt   endp
  159. ;----------------------- routine ends --------------------------------+
  160. ;----------------------- routine begins ------------------------------+
  161. ; ROUTINE TO RETURN COLOR OF A POINT ON MEDIUM RES COLOR SCREEN
  162. ;
  163. locate  proc    far
  164. ;
  165.         push    bx              ; save registers
  166.         push    cx
  167. ;
  168. ; multiply y-coord by bytes per row and adjust for even/odd lines
  169.         mov     ax,di           ; get y-coord into low part
  170.         mov     ah,al           ;  and into high part
  171.         and     ax,01FEh        ; mask off unwanted parts
  172.         sal     ax,1            ; times 4
  173.         sal     ax,1            ; times 8
  174.         sal     ax,1            ; times 16
  175.         mov     bx,ax           ; goes into address
  176.         and     bh,7            ; without adjustment
  177.         sal     ax,1            ; times 32
  178.         sal     ax,1            ; times 64
  179.         add     bx,ax           ; address gets times 64 + times 16
  180. ;
  181. ; add x-coord to address
  182.         mov     ax,si           ; get x-coordinate
  183.         sar     ax,1            ; divide
  184.         sar     ax,1            ; by 4
  185.         add     bx,ax           ; here is the address
  186. ;
  187. ; compute the position of the pixel in the byte
  188.         mov     cx,si           ; use x-coordinate to determine count
  189.         and     cx,3            ; just the bit count
  190.         inc     cx              ; plus one
  191.         sal     cx,1            ; 2 bits per pixel
  192. ;
  193. ; get the byte and rotate into place
  194.         mov     al,es:[bx]      ; get old byte
  195.         rol     al,cl           ; rotate left this many times
  196.         and     ax,3            ; just the pixel color
  197. ;
  198.         pop     cx              ; restore the registers
  199.         pop     bx
  200.         ret
  201. ;
  202. locate  endp
  203. ;----------------------- routine ends --------------------------------+
  204. ;----------------------- routine begins ------------------------------+
  205. ; ROUTINE TO FILL A RECTANGULAR BOX
  206. ;
  207. setbox  proc    far
  208. ;
  209.         push    si              ; save registers
  210.         push    di
  211.         push    dx
  212.         push    bx
  213.         push    cx
  214.         push    ax
  215. ;
  216. ; determine byte position for start
  217. ;
  218. ; get y contribution
  219.         mov     ax,y1           ; get starting y-coordinate
  220.         mov     ah,al           ; replicate for odd/even bank
  221.         and     ax,1FEh         ; just one bit gets moved
  222.         sal     ax,1            ; times 4
  223.         sal     ax,1            ; times 8
  224.         sal     ax,1            ; times 16
  225.         mov     di,ax           ; address gets 16 times y-coordinate
  226.         and     di,7FFh         ; not the odd/even bit
  227.         sal     ax,1            ; times 32
  228.         sal     ax,1            ; times 64
  229.         add     di,ax           ; address gets 80 times y-coordinate
  230. ;
  231. ; add in x contribution
  232.         mov     ax,x1           ; get x-coordinate
  233.         sar     ax,1            ; divide
  234.         sar     ax,1            ;  by 4
  235.         add     di,ax           ; beginning offset
  236. ;
  237. ; count for outer loop
  238.         mov     cx,y2           ; ending y-coordinate
  239.         sub     cx,y1           ; minus starting y-coordinate
  240.         inc     cx              ; plus one
  241. ;
  242. ; count for inner loop
  243.         mov     si,x2           ; ending x-coordinate
  244.         sar     si,1            ; divide
  245.         sar     si,1            ;  by 4
  246.         mov     ax,x1           ; starting x-coordinate
  247.         sar     ax,1            ; divide
  248.         sar     ax,1            ;  by 4
  249.         sub     si,ax           ; take the difference
  250. ;
  251. ; get the color 
  252.         mov     bx,color        ; get the color
  253.         and     bx,3            ; just between 0 and 3
  254.         mov     dl,cbytes[bx]   ; look up color pattern
  255. ;
  256. ; determine mask for start and ending bytes
  257.         mov     bx,x1           ; starting byte
  258.         and     bx,3            ; just the pixel position 
  259.         sal     bx,1            ; times 2
  260.         sal     bx,1            ; times 4
  261.         mov     ax,x2           ; ending byte
  262.         and     ax,3            ; just the pixel position
  263.         add     bx,ax           ; 4*starting+ending
  264.         sal     bx,1            ; 8*starting+2*ending
  265.         mov     bx,xtable[bx]   ; look up the masks
  266. ;
  267. ; set up masked color bytes
  268.         mov     dh,dl           ; color for left bytes
  269.         mov     ah,dl           ; color for middle bytes
  270.         and     dx,bx           ; mask left and right color bytes
  271. ;
  272.         cld                     ; forward
  273. ;
  274. sboxloop:
  275.         push    cx              ; save count of outer loop
  276.         push    di              ; save initial byte position
  277. ;
  278.         mov     cx,si           ; count for inner loop
  279. ;
  280. ; check for only one byte
  281.         mov     al,bh           ; get the mask
  282.         jcxz    sboxloop2       ; if ending byte coincides
  283. ;
  284. ; color leftmost byte of the scan line
  285.         not     al              ; reverse the mask for clearing
  286.         and     al,es:[di]      ; get byte from memory and clear pixels
  287.         or      al,dh           ; put color in place
  288.         stosb                   ; put byte in place
  289. ;
  290. ; check for just two bytes
  291.         dec     cx              ; count the byte
  292.         jcxz    sboxloop1       ; done?
  293. ;
  294. ; color middle bytes of the scan line
  295.         mov     al,ah           ; color for middle bytes
  296.         rep     stosb           ; put middle bytes in place
  297. ;
  298. ; handle rightmost byte of the scan line
  299. ;
  300. ; come here if two or more bytes
  301. sboxloop1:
  302.         mov     al,0FFh         ; set full mask
  303. ;
  304. ; in any case come here to adjust the masks
  305. sboxloop2:
  306.         and     al,bl           ; bring in right part of mask
  307.         and     dl,al           ; clear left part of color if needed
  308. ;
  309. ; color the byte
  310.         not     al              ; reverse the mask for clearing
  311.         and     al,es:[di]      ; get byte from memory and clear pixels
  312.         or      al,dl           ; put pixels in the byte
  313.         stosb                   ; put byte back into video RAM
  314. ;
  315. ; compute next scan line
  316.         pop     di              ; retore address of left side of box
  317.         test    di,2000h        ; odd or even line?
  318.         jz      sboxloop3       ; skip if even
  319.         add     di,80           ; add 80 bytes per line
  320. sboxloop3:
  321.         xor     di,2000h        ; changes banks in any case
  322.         pop     cx              ; restore count for outer loop
  323.         loop    sboxloop        ; next scan line
  324. ;
  325.         pop     ax              ; restore registers
  326.         pop     cx
  327.         pop     bx
  328.         pop     dx
  329.         pop     di
  330.         pop     si
  331.         ret
  332. ;
  333. setbox  endp
  334. ;----------------------- routine ends --------------------------------+
  335. ;----------------------- routine begins ------------------------------+
  336. ; ROUTINE TO XOR A RECTANGULAR BOX
  337. ;
  338. xorbox  proc    far
  339. ;
  340.         push    si              ; save registers
  341.         push    di
  342.         push    dx
  343.         push    bx
  344.         push    cx
  345.         push    ax
  346. ;
  347. ; determine byte position for start
  348. ;
  349. ; get y contribution
  350.         mov     ax,y1           ; get starting y-coordinate
  351.         mov     ah,al           ; replicate for odd/even bank
  352.         and     ax,1FEh         ; just one bit gets moved
  353.         sal     ax,1            ; times 4
  354.         sal     ax,1            ; times 8
  355.         sal     ax,1            ; times 16
  356.         mov     di,ax           ; address gets 16 times y-coordinate
  357.         and     di,7FFh         ; not the odd/even bit
  358.         sal     ax,1            ; times 32
  359.         sal     ax,1            ; times 64
  360.         add     di,ax           ; address gets 80 times y-coordinate
  361. ;
  362. ; add in x contribution
  363.         mov     ax,x1           ; get x-coordinate
  364.         sar     ax,1            ; divide
  365.         sar     ax,1            ;  by 4
  366.         add     di,ax           ; beginning offset
  367. ;
  368. ; count for outer loop
  369.         mov     cx,y2           ; ending y-coordinate
  370.         sub     cx,y1           ; minus starting y-coordinate
  371.         inc     cx              ; plus one
  372. ;
  373. ; count for inner loop
  374.         mov     si,x2           ; ending x-coordinate
  375.         sar     si,1            ; divide
  376.         sar     si,1            ;  by 4
  377.         mov     ax,x1           ; starting x-coordinate
  378.         sar     ax,1            ; divide
  379.         sar     ax,1            ;  by 4
  380.         sub     si,ax           ; take the difference
  381. ;
  382. ; get the color 
  383.         mov     bx,color        ; get the color
  384.         and     bx,3            ; just between 0 and 3
  385.         mov     dl,cbytes[bx]   ; look up color pattern
  386. ;
  387. ; determine mask for start and ending bytes
  388.         mov     bx,x1           ; starting byte
  389.         and     bx,3            ; just the pixel position 
  390.         sal     bx,1            ; times 2
  391.         sal     bx,1            ; times 4
  392.         mov     ax,x2           ; ending byte
  393.         and     ax,3            ; just the pixel position
  394.         add     bx,ax           ; 4*starting+ending
  395.         sal     bx,1            ; 8*starting+2*ending
  396.         mov     bx,xtable[bx]   ; look up the masks
  397. ;
  398. ; set up masked color bytes
  399.         mov     dh,dl           ; color for left bytes
  400.         mov     ah,dl           ; color for middle bytes
  401.         and     dx,bx           ; mask left and right color bytes
  402. ;
  403.         cld                     ; forward direction
  404. ;
  405. xboxloop:
  406.         push    cx              ; save count for outer loop
  407.         push    di              ; save address of leftmost byte
  408. ;
  409.         mov     cx,si           ; count for inner loop
  410. ;
  411. ; check if only one byte in a scan line
  412.         mov     al,bh           ; get the mask
  413.         jcxz    xboxloop3       ; ending byte coincides
  414. ;
  415. ; xor the leftmost byte
  416.         xor     es:[di],dh      ; xor color into memory
  417.         inc     di              ; next byte
  418.         dec     cx              ; count it
  419.         jcxz    xboxloop2       ; done?
  420. ;
  421. ; xor the middle bytes
  422. xboxloop1:
  423.         xor     es:[di],ah      ; xor color byte into memory
  424.         inc     di              ; next byte
  425.         loop    xboxloop1       ; loop to get all the middle
  426. ;
  427. ; handle the rightmost byte
  428. ;
  429. ; come here if two or more bytes
  430. xboxloop2:
  431.         mov     al,0FFh         ; set full mask
  432. ;
  433. ; in any case come here to adjust
  434. xboxloop3:
  435.         and     al,bl           ; bring in right part
  436.         and     dl,al           ; mask the color if needed
  437. ;
  438. ; xor the rightmost byte
  439.         xor     es:[di],dl      ; xor byte into memory
  440.         inc     di              ; next byte
  441. ;
  442.         pop     di              ; restore the leftmost address
  443.         test    di,2000h        ; odd or even scan line?
  444.         jz      xboxloop4       ; skip if even
  445.         add     di,80           ; add 80 if odd
  446. xboxloop4:
  447.         xor     di,2000h        ; switch banks in any case
  448.         pop     cx              ; restore count of outer loop
  449.         loop    xboxloop        ; loop for next scan line
  450. ;
  451.         pop     ax              ; restore registers
  452.         pop     cx
  453.         pop     bx
  454.         pop     dx
  455.         pop     di
  456.         pop     si
  457.         ret
  458. ;
  459. xorbox  endp
  460. ;----------------------- routine ends --------------------------------+
  461. ex4prim ends                    ; end of code segment
  462. ;
  463.         end
  464.